package com.lixin.juc.blockingqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

// 阻塞队列
public class MainApplication {

    public static void main(String[] args) {
        //testException();
        //testNoException();
        //testForeverBlocking();
        testTimeoutBlocking();
    }

    public static void testTimeoutBlocking() {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        try {
            System.out.println(queue.offer("one"));
            System.out.println(queue.offer("two"));
            System.out.println(queue.offer("three"));

            // 这里会阻塞，因为队列已满，但如果2秒后依然不能把four放到队列中，就返回false并继续往下执行
            System.out.println(queue.offer("four", 2, TimeUnit.SECONDS));
            System.out.println("已过2秒，不等了");

            System.out.println(queue.poll());
            System.out.println(queue.poll());
            System.out.println(queue.poll());

            // 这里会阻塞，因为队列中的元素已被全部取出，但如果2秒后依然取不到元素，就返回null并继续往下执行
            System.out.println(queue.poll(2, TimeUnit.SECONDS));
            System.out.println("已过2秒，不等了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void testForeverBlocking() {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
        try {
            queue.put("one");
            queue.put("two");
            queue.put("three");

            // 这里会一直阻塞，因为队列已满
            //queue.put("four");

            System.out.println(queue.take());
            System.out.println(queue.take());
            System.out.println(queue.take());

            // 这里会一直阻塞，因为队列中的元素已被全部取出
            //System.out.println(queue.take());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testNoException() {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        // 查看队首元素，会返回null，不会抛出异常
        System.out.println(queue.peek());

        System.out.println(queue.offer("one"));
        System.out.println(queue.offer("two"));
        System.out.println(queue.offer("three"));

        // 不会抛出异常，会返回false，因为队列已满
        //System.out.println(queue.offer("four"));

        // 查看队首元素
        System.out.println(queue.element());

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());

        // 不会抛出异常，会返回null，因为队列中的3个元素已被全部取出
        System.out.println(queue.poll());
    }

    public static void testException() {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        // 查看队首元素，会抛出java.util.NoSuchElementException异常，因为队首没有元素
        //System.out.println(queue.element());

        System.out.println(queue.add("one"));
        System.out.println(queue.add("two"));
        System.out.println(queue.add("three"));

        // 会抛出Queue full异常，因为队列已满
        //System.out.println(queue.add("four"));

        // 查看队首元素
        System.out.println(queue.element());

        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());

        // 会抛出java.util.NoSuchElementException异常，因为队列中的3个元素已被全部取出
        //System.out.println(queue.remove());
    }

}
